package com.huilian.iotbox.aliyun.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.iot.model.v20180120.PubResponse;
import com.huilian.iotbox.data.constants.IotConstant;
import com.huilian.iotbox.aliyun.openapi.MessageBrokerManager;
import com.huilian.iotbox.aliyun.service.PubService;
import com.huilian.iotbox.data.enums.MessageLogResultEnum;
import com.huilian.iotbox.data.enums.MessageLogTypeEnum;
import com.huilian.iotbox.data.po.MessageLog;
import com.huilian.iotbox.data.producer.MessageLogRabbit;
import com.huilian.iotbox.data.service.DeviceCommonService;
import com.huilian.iotbox.data.service.ErrorLogCommonService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Date;

/**
 * PubServiceImpl
 * 消息发布
 *
 * @Author mineChen
 * @Date 2021/9/1 上午 09:54
 */
@Service
@Slf4j
public class PubServiceImpl implements PubService {


    @Value("${huilian.iot.productKey}")
    private String productKey;
    @Value("${huilian.iot.apiProductKey}")
    private String apiProductKey;
    @Value("${huilian.iot.iotInstanceId:#{null}}")
    private String iotInstanceId;
    @Autowired
    private ErrorLogCommonService errorLogCommonService;
    @Autowired
    private MessageLogRabbit messageLogRabbit;
    @Autowired
    private DeviceCommonService deviceCommonService;

    @Override
    public boolean pub(String command, String deviceNo, String productKey) {
       return this.pubPublic(command,deviceNo,productKey,false);
    }

    @Override
    public boolean pub(String command, String deviceNo, String productKey, boolean isItReceived) {
        return this.pubPublic(command,deviceNo,productKey,isItReceived);
    }
    public boolean pubPublic(String command, String deviceNo, String productKey, boolean isItReceived) {
        Integer serviceProvider = deviceCommonService.getServiceProvider(deviceNo);
        MessageLog messageLog = new MessageLog();
        messageLog.setContent(command);
        messageLog.setDeviceNo(deviceNo);
        messageLog.setType(MessageLogTypeEnum.SEND.getCode());
        messageLog.setCreateTime(new Date());
        try {
            switch (serviceProvider) {
                case 1:
                    log.info("aLiYunPub");
//                    return this.aLiYunPub(messageLog, productKey);
                case 2:
                    log.info("emqxPub");
                    return this.emqxPub(messageLog, productKey,isItReceived);
                default:
                    log.error("serviceProvider异常，发送不成功");
                    errorLogCommonService.writerInfoErrorLog("serviceProvider异常，发送不成功", serviceProvider);
                    return false;
            }
        } catch (Exception e) {
            log.error("消息发送失败，发送出现异常");
            errorLogCommonService.writerInfoErrorLog("消息发送失败，发送出现异常", e);
            messageLog.setResult(MessageLogResultEnum.FAIL.getCode());
            e.printStackTrace();
            return false;
        } finally {
            switch (serviceProvider) {
                case 1:
                    messageLogRabbit.sendMessageLog(messageLog);
            }
        }
    }
    /**
     * 向EMQX发送消息
     *
     * @param messageLog
     * @param productKey
     * @param isItReceived
     * @return
     */
    private boolean emqxPub(MessageLog messageLog, String productKey,Boolean isItReceived) {

        String getTopic;
        if (isItReceived || productKey.equalsIgnoreCase(apiProductKey)){
            getTopic = String.format(IotConstant.UPDATE_TOPIC_SUFFIX, productKey, messageLog.getDeviceNo());
        } else {
            getTopic = String.format(IotConstant.GET_TOPIC, productKey, messageLog.getDeviceNo());
        }
        messageLog.setTopic(getTopic);

        messageLogRabbit.sendEMQXMessageToConsume(messageLog);
        return true;
    }

    /**
     * 向阿里云MQTT发送消息
     *
     * @param messageLog
     * @param productKey
     * @return
     */
    private boolean aLiYunPub(MessageLog messageLog, String productKey) {
        final String getTopic = String.format(IotConstant.GET_TOPIC, productKey, messageLog.getDeviceNo());
        PubResponse pubResponse = MessageBrokerManager.pub(productKey,
                getTopic,
                Base64.encodeBase64String(messageLog.getContent().getBytes()),
                0, iotInstanceId);
        if (ObjectUtils.isEmpty(pubResponse)) {
            log.error("消息发送失败，请求体为空");
            errorLogCommonService.writerInfoErrorLog("消息发送失败，请求体为空", getTopic);
            messageLog.setResult(MessageLogResultEnum.FAIL.getCode());
            return false;
        }
        if (!pubResponse.getSuccess()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("pubResponse", pubResponse);
            jsonObject.put("messageLog", messageLog);
            log.error("消息发送失败，发送状态为失败:" + JSON.toJSONString(jsonObject));
            errorLogCommonService.writerInfoErrorLog("消息发送失败，发送状态为失败", jsonObject);
            messageLog.setResult(MessageLogResultEnum.FAIL.getCode());
            return false;
        }
        messageLog.setTopic(getTopic);
        messageLog.setResult(MessageLogResultEnum.SUCCESS.getCode());
        return true;
    }
}
